#ifndef __AI_SERVICE_UTILS_H__
#define __AI_SERVICE_UTILS_H__

#include <string.h>
#include <string>
#include <sys/time.h>

#ifndef _NDEBUG
    #include <stdio.h>
    #define PERF(name) Perf perf(name)
    #define FILE_NAME (strrchr(__FILE__,'/') ? strrchr(__FILE__,'/') + 1 : __FILE__)
    #define LOG(LEVEL, FORMAT, ...) printf("[%s][%s]:[%s]:[%d] " FORMAT "\n", #LEVEL, FILE_NAME,__FUNCTION__,__LINE__,##__VA_ARGS__)
#else
    #define LOG(LEVEL, FORMAT, ...) NULL
    #define PERF(name) NULL
#endif

#define LOG_ERROR(FORMAT, ...) LOG(ERROR, FORMAT, ##__VA_ARGS__)
#define LOG_WARN(FORMAT, ...) LOG(WARNING, FORMAT, ##__VA_ARGS__)
#define LOG_INFO(FORMAT, ...) LOG(INFO, FORMAT, ##__VA_ARGS__)
#define LOG_DEBUG(FORMAT, ...) LOG(DEBUG, FORMAT, ##__VA_ARGS__)

namespace ai_service {

struct Config;
class AsyncTaskQueue;

enum Ret {
    RET_OK = 0,
    // TaskQueue
    RET_TASK_QUEUE_FULL = 1,
    RET_TASK_QUEUE_EMPTY = 2,
    RET_USER_HAS_REGISTERED = 3,
}; // Ret

class Perf {
    public:
        Perf() {
            gettimeofday(&m_start, NULL);
        }
        ~Perf() {}
        void update() {
            gettimeofday(&m_start, NULL);
        }    
        void tick(const std::string& name) {
            gettimeofday(&m_end, NULL);
            double t = (m_end.tv_sec - m_start.tv_sec) * 1000.0 + (m_end.tv_usec - m_start.tv_usec) / 1000.0;
            LOG_INFO("block: %s, time elapse: %f ms", name.c_str(), t);
        }
    private:
        struct timeval m_start;
        struct timeval m_end;
        std::string m_name;
}; // class Perf
    



} // namespace ai_service

#endif // __AI_SERVICE_UTILS_H__